﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows;
using Wpf.Ui.Controls;
using Wpf.Ui;
using ClientAppraise.Controls;

namespace ClientAppraise.Services.Impl
{
    public class ZxContentDialogService : IZxContentDialogService
    {
        private readonly List<KeyValuePair<int, ContentPresenter>> contents = new();

        private ContentDialog? _dialog;

        public ContentPresenter? EjectContentPresenter(int HashCode)
        {
            var value = contents.FirstOrDefault(t => t.Key == HashCode);

            if (!value.Equals(default(KeyValuePair<int, ContentPresenter>)))
            {
                contents.Remove(value);
            }

            var myReturn = value.Equals(default(KeyValuePair<int, ContentPresenter>)) ? value.Value : null;

            return myReturn;
        }
        public ContentPresenter? GetContentPresenter(int HashCode)
        {
            var value = contents.FirstOrDefault(t => t.Key == HashCode);

            if (value.Equals(default(KeyValuePair<int, ContentPresenter>)))
            {
                if (contents.Count > 0)
                {
                    return contents[^1].Value;
                }
            }

            var myReturn = value.Equals(default(KeyValuePair<int, ContentPresenter>)) ? null : value.Value;

            return myReturn;
        }
        public ContentPresenter GetContentPresenter()
        {
            var code = 0;
            foreach (Window window in Application.Current.Windows)
            {
                if (window.IsActive)//使用窗体类进行匹配查找
                {
                    code = window.GetHashCode();
                    break;
                }
            }

            var re= GetContentPresenter(code);

            return re ?? throw new InvalidOperationException();
        }
        public void PushContentPresenter(int HashCode, ContentPresenter? contentPresenter)
        {
            if (contentPresenter == null) return;

            if (!Application.Current.Dispatcher.CheckAccess())
            {
                Application.Current.Dispatcher.Invoke(new Action(() => PushContentPresenter(HashCode, contentPresenter)));
                return;
            }


            var value = contents.FirstOrDefault(t => t.Key == HashCode);

            if (value.Equals(default(KeyValuePair<int, ContentPresenter>)))
            {
                contents.Add(new KeyValuePair<int, ContentPresenter>(HashCode, contentPresenter));
            }

        }
        public void SetContentPresenter(ContentPresenter contentPresenter)
        {
            contents.Clear();
            var code = 0;
            foreach (Window window in Application.Current.Windows)
            {
                if (window.IsActive)//使用窗体类进行匹配查找
                {
                    code = window.GetHashCode();
                    break;
                }
            }
            PushContentPresenter(code, contentPresenter);
        }
        public Task<ContentDialogResult> ShowAlertAsync(string title, string message, string closeButtonText, CancellationToken cancellationToken = default)
        {
            if (!Application.Current.Dispatcher.CheckAccess())
            {
                return Application.Current.Dispatcher.Invoke(new Func<Task<ContentDialogResult>>(() => ShowAlertAsync(title, message, closeButtonText, cancellationToken)));
            }

            var presenter = GetContentPresenter();

            if (presenter is null)
            {
                throw new ArgumentNullException($"The ContentPresenter didn't set previously.");
            }

            var _dialog = new ContentDialog(presenter);

            _dialog.Title = title;
            _dialog.Content = message;
            _dialog.CloseButtonText = closeButtonText;

            return _dialog.ShowAsync(cancellationToken);
        }

        public Task<ContentDialogResult> ShowProgressLoadingAsync(Action action, string title = "加载中", bool IsIndeterminate = false)
        {
            if (!Application.Current.Dispatcher.CheckAccess())
            {
                return Application.Current.Dispatcher.Invoke(new Func<Task<ContentDialogResult>>(() => ShowProgressLoadingAsync(action, title, IsIndeterminate)));
            }

            var presenter = GetContentPresenter();

            if (presenter is null)
            {
                throw new ArgumentNullException($"The ContentPresenter didn't set previously.");
            }

            _dialog = new ZxProgressLoading(presenter);

            _dialog.Opened += (ContentDialog sender, System.Windows.RoutedEventArgs args) =>
            {
                Task.Run(() => { action?.Invoke(); });
            };


            ((ZxProgressLoading)(_dialog)).GetProgress.IsIndeterminate = IsIndeterminate;

            _dialog.Title = title;


            return _dialog.ShowAsync();
        }

        public Task<ContentDialogResult> ShowRingLoadingAsync(Action action, string title = "加载中", bool IsIndeterminate = true)
        {
            if (!Application.Current.Dispatcher.CheckAccess())
            {
                return Application.Current.Dispatcher.Invoke(new Func<Task<ContentDialogResult>>(() => ShowRingLoadingAsync(action, title, IsIndeterminate)));
            }
            var presenter = GetContentPresenter() ?? throw new ArgumentNullException($"The ContentPresenter didn't set previously.");

            _dialog = new ZxRingLoading(presenter);
            _dialog.Opened += (ContentDialog sender, System.Windows.RoutedEventArgs args) =>
            {
                Task.Run(() => { action?.Invoke(); });
            };


            ((ZxRingLoading)(_dialog)).GetProgress.IsIndeterminate = IsIndeterminate;

            _dialog.Title = title;

            return _dialog.ShowAsync();
        }

        /// <summary>
        /// 这个要改为错误关闭，以通知道打开方
        /// </summary>
        public void SetLoadingError()
        {
            if (_dialog == default) return;

            if (!_dialog.Dispatcher.CheckAccess())
            {
                _dialog.Dispatcher.BeginInvoke(() => SetLoadingError());
                return;
            }

            if (_dialog is ContentDialog loading1)
            {
                loading1.Hide(ContentDialogResult.Secondary);
            }
        }

        public void CloseLoading()
        {
            if (_dialog == default) return;

            if (!_dialog.Dispatcher.CheckAccess())
            {
                _dialog.Dispatcher.BeginInvoke(() => CloseLoading());
                return;
            }
            _dialog?.Hide(ContentDialogResult.Primary);
        }

        public void SetLoadingPercent(double percent, string title = "")
        {
            if (_dialog == default) return;

            if (!_dialog.Dispatcher.CheckAccess())
            {
                _dialog.Dispatcher.BeginInvoke(() => SetLoadingPercent(percent, title));
                return;
            }

            if (_dialog is ZxProgressLoading loading1)
            {
                if (!string.IsNullOrEmpty(title))
                {
                    loading1.GetLabel.Content = title;
                }

                loading1.GetProgress.Value = percent;

                if (percent >= loading1.GetProgress.Maximum)
                {
                    _dialog.Hide();
                }

            }
            if (_dialog is ZxRingLoading loading)
            {
                loading.GetLabel.Content = title;
                loading.GetProgress.Progress = percent;

                if (percent >= 100)
                {
                    _dialog.Hide();
                }
            }
        }

        public ContentDialog? GetDialog => _dialog;

        public Task<ContentDialogResult> ShowSimpleDialogAsync(SimpleContentDialogCreateOptions options, CancellationToken cancellationToken = default)
        {

            if (!Application.Current.Dispatcher.CheckAccess())
            {
                return Application.Current.Dispatcher.Invoke(new Func<Task<ContentDialogResult>>(() => ShowSimpleDialogAsync(options, cancellationToken)));
            }

            var presenter = GetContentPresenter();

            if (presenter is null)
            {
                throw new ArgumentNullException($"The ContentPresenter didn't set previously.");
            }


            var dialog = new ContentDialog(presenter)
            {
                Title = options.Title,
                Content = options.Content,
                CloseButtonText = options.CloseButtonText,
                PrimaryButtonText = options.PrimaryButtonText,
                SecondaryButtonText = options.SecondaryButtonText
            };

            return dialog.ShowAsync(cancellationToken);
        }
        public void UnSetContentPresenter()
        {
            contents.Clear();
        }

        public Task<ContentDialogResult> ShowAsync(ContentDialog dialog, CancellationToken cancellationToken)
        {
            throw new NotImplementedException();
        }
    }

}
